/**
 * @file main.cpp
 * @brief 认证服务启动入口 - 游戏微服务架构的认证服务主程序
 * @author 29108
 * @date 2025/7/21
 * @version 1.0
 *
 * 功能特性:
 * - 服务启动和初始化
 * - 配置文件加载
 * - 信号处理
 * - 优雅关闭
 * - 错误处理和恢复
 *
 * 启动流程:
 * 1. 加载配置文件
 * 2. 初始化日志系统
 * 3. 创建认证服务实例
 * 4. 初始化服务组件
 * 5. 启动HTTP服务器
 * 6. 注册到API Gateway
 * 7. 等待信号处理
 */

#include "core_services/auth_service/auth_service.h"
#include "core_services/auth_service/startup_monitor.h"
#include "common/config/config_manager.h"
#include "common/logger/logger.h"
#include <iostream>
#include <csignal>
#include <memory>
#include <thread>
#include <chrono>
#include <filesystem>
#include <fstream>
#include <algorithm>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
// 移除PID文件锁相关头文件

using namespace core_services::auth_service;

// 全局服务实例指针
std::unique_ptr<AuthService> g_auth_service = nullptr;

/**
 * @brief 信号处理函数
 * @param signal 信号值
 */
void signalHandler(int signal) {
    const char* signal_name = "UNKNOWN";
    switch (signal) {
        case SIGINT: signal_name = "SIGINT"; break;
        case SIGTERM: signal_name = "SIGTERM"; break;
        case SIGHUP: signal_name = "SIGHUP"; break;
        case SIGABRT: signal_name = "SIGABRT"; break;
        case SIGSEGV: signal_name = "SIGSEGV"; break;
        default: break;
    }

    std::cerr << "收到信号: " << signal_name << " (" << signal << ")" << std::endl;

    switch (signal) {
        case SIGINT:
        case SIGTERM:
            LOG_INFO("收到终止信号: " + std::string(signal_name) + "，开始优雅关闭服务...");
            if (g_auth_service) {
                g_auth_service->stop();
            }
            break;
        case SIGHUP:
            LOG_INFO("收到重新加载信号，重启服务...");
            if (g_auth_service) {
                g_auth_service->restart();
            }
            break;
        case SIGABRT:
        case SIGSEGV:
            // 对于严重错误信号，记录信息并立即退出
            std::cerr << "程序异常终止，信号: " << signal_name << std::endl;
            LOG_ERROR("程序异常终止，信号: " + std::string(signal_name));

            // 对于严重错误，不尝试清理，直接退出避免进一步损坏
            // 设置全局指针为nullptr，避免析构时的问题
            if (g_auth_service) {
                g_auth_service.release(); // 释放所有权但不调用析构函数
            }

            // 使用_exit避免调用析构函数和atexit处理器
            _exit(signal == SIGABRT ? 134 : 139);
            break;
        default:
            LOG_WARNING("收到未处理的信号: " + std::to_string(signal));
            break;
    }
}

/**
 * @brief 注册信号处理器
 */
void registerSignalHandlers() {
    std::signal(SIGINT, signalHandler);   // Ctrl+C
    std::signal(SIGTERM, signalHandler);  // 终止信号
    std::signal(SIGHUP, signalHandler);   // 重新加载信号
    std::signal(SIGABRT, signalHandler);  // 异常终止信号
    std::signal(SIGSEGV, signalHandler);  // 段错误信号
    
    // 忽略SIGPIPE信号（避免网络连接断开时程序崩溃）
    std::signal(SIGPIPE, SIG_IGN);
}

/**
 * @brief 打印启动横幅
 */
void printBanner() {
    std::cout << R"(
    ╔══════════════════════════════════════════════════════════════╗
    ║                    游戏微服务认证服务                          ║
    ║                   Game Microservices Auth Service            ║
    ║                                                              ║
    ║  版本: 1.0.0                                                 ║
    ║  作者: 29108                                                 ║
    ║  日期: 2025/7/21                                             ║
    ║                                                              ║
    ║  功能特性:                                                    ║
    ║  • 用户注册和登录认证                                          ║
    ║  • JWT令牌管理                                               ║
    ║  • 游戏登录和服务器分配                                        ║
    ║  • 多设备会话管理                                             ║
    ║  • 实时状态同步                                               ║
    ║  • 与API Gateway协作                                         ║
    ║  • 基于Kafka的事件驱动                                        ║
    ╚══════════════════════════════════════════════════════════════╝
)" << std::endl;
}

/**
 * @brief 验证配置文件是否存在
 * @param config_file 配置文件路径
 * @return 文件存在且可读返回true
 */
bool validateConfigFile(const std::string& config_file) {
    // 检查文件是否存在
    if (!std::filesystem::exists(config_file)) {
        std::cerr << "错误: 配置文件不存在: " << config_file << std::endl;
        return false;
    }

    // 检查文件是否可读
    std::ifstream file(config_file);
    if (!file.is_open()) {
        std::cerr << "错误: 无法读取配置文件: " << config_file << std::endl;
        return false;
    }
    file.close();

    // 检查文件扩展名
    std::string extension = std::filesystem::path(config_file).extension().string();
    std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
    if (extension != ".yml" && extension != ".yaml" && extension != ".json") {
        std::cerr << "错误: 不支持的配置文件格式: " << extension << std::endl;
        std::cerr << "支持的格式: .yml, .yaml, .json" << std::endl;
        return false;
    }

    return true;
}

/**
 * @brief 加载配置文件
 * @param config_file 配置文件路径
 * @return 加载成功返回true
 */
bool loadConfiguration(const std::string& config_file) {
    try {
        auto& monitor = core_services::auth_service::getStartupMonitor();
        monitor.setStage(core_services::auth_service::StartupStage::LOADING_CONFIG);

        std::cout << "正在验证配置文件..." << std::endl;

        // 验证配置文件
        if (!validateConfigFile(config_file)) {
            monitor.recordError("ConfigFile", "配置文件验证失败: " + config_file);
            return false;
        }

        std::cout << "正在加载配置文件: " << config_file << std::endl;

        auto& config_manager = common::config::ConfigManager::getInstance();

        // 加载配置文件
        if (!config_manager.loadFromFile(config_file)) {
            std::cerr << "错误: 无法加载配置文件: " << config_file << std::endl;
            monitor.recordError("ConfigManager", "无法加载配置文件: " + config_file);
            return false;
        }

        // 验证配置完整性
        auto validation_errors = config_manager.getValidationErrors();
        if (!validation_errors.empty()) {
            std::cerr << "错误: 配置文件验证失败:" << std::endl;
            for (const auto& error : validation_errors) {
                std::cerr << "  - " << error << std::endl;
                monitor.recordError("ConfigValidation", error);
            }
            return false;
        }

        monitor.recordSuccess("ConfigManager", "配置文件加载成功: " + config_file);
        std::cout << "配置文件加载成功: " << config_file << std::endl;
        return true;
    } catch (const std::exception& e) {
        std::cerr << "错误: 加载配置文件时发生异常: " << e.what() << std::endl;
        core_services::auth_service::getStartupMonitor().recordError("ConfigManager",
            "加载配置文件异常: " + std::string(e.what()));
        return false;
    }
}

/**
 * @brief 初始化日志系统
 * @return 初始化成功返回true
 */
bool initializeLogging() {
    try {
        auto& monitor = core_services::auth_service::getStartupMonitor();
        monitor.setStage(core_services::auth_service::StartupStage::INITIALIZING_LOGGING);

        std::cout << "正在初始化日志系统..." << std::endl;

        auto& config_manager = common::config::ConfigManager::getInstance();

        // 获取日志配置
        std::string log_level = config_manager.get<std::string>("logging.level", "INFO");
        std::string log_file = config_manager.get<std::string>("logging.file", "logs/auth_service.log");
        bool enable_console = config_manager.get<bool>("logging.console", true);

        // 创建日志目录（如果不存在）
        std::filesystem::path log_path(log_file);
        if (log_path.has_parent_path()) {
            std::filesystem::create_directories(log_path.parent_path());
        }

        // 初始化日志系统
        common::logger::Logger::getInstance().initializeFromConfig();

        LOG_INFO("=== 认证服务日志系统启动 ===");
        LOG_INFO("日志级别: " + log_level);
        LOG_INFO("日志文件: " + log_file);
        LOG_INFO("控制台输出: " + std::string(enable_console ? "启用" : "禁用"));
        LOG_INFO("日志系统初始化成功");

        monitor.recordSuccess("Logger", "日志系统初始化成功");
        std::cout << "日志系统初始化成功" << std::endl;
        return true;
    } catch (const std::exception& e) {
        std::cerr << "错误: 初始化日志系统时发生异常: " << e.what() << std::endl;
        core_services::auth_service::getStartupMonitor().recordError("Logger",
            "日志系统初始化异常: " + std::string(e.what()));
        return false;
    }
}

/**
 * @brief 执行启动前置检查
 * @return 检查通过返回true
 */
bool performPreStartupChecks() {
    try {
        auto& monitor = core_services::auth_service::getStartupMonitor();
        monitor.setStage(core_services::auth_service::StartupStage::CHECKING_DEPENDENCIES);

        LOG_INFO("=== 执行启动前置检查 ===");

        auto& config_manager = common::config::ConfigManager::getInstance();

        // 检查端口可用性
        std::string host = config_manager.get<std::string>("service.host", "localhost");
        int port = config_manager.get<int>("service.port", 8008);

        LOG_INFO("检查端口可用性: " + host + ":" + std::to_string(port));

        // 简单的端口检查（尝试绑定）
        int sock = socket(AF_INET, SOCK_STREAM, 0);
        if (sock < 0) {
            LOG_ERROR("无法创建socket进行端口检查");
            monitor.recordError("PortCheck", "无法创建socket进行端口检查");
            return false;
        }

        struct sockaddr_in addr;
        addr.sin_family = AF_INET;
        addr.sin_port = htons(port);
        addr.sin_addr.s_addr = INADDR_ANY;

        int reuse = 1;
        setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));

        if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
            close(sock);
            LOG_WARNING("端口 " + std::to_string(port) + " 可能被占用，但由于SO_REUSEADDR设置，继续启动");
            monitor.recordSuccess("PortCheck", "端口检查完成（可能被占用但允许重用）");
        } else {
            close(sock);
            LOG_INFO("端口检查通过");
            monitor.recordSuccess("PortCheck", "端口完全可用");
        }

        // 检查必要的目录
        std::vector<std::string> required_dirs = {
            "logs",
            "data",
            "temp"
        };

        for (const auto& dir : required_dirs) {
            if (!std::filesystem::exists(dir)) {
                LOG_INFO("创建目录: " + dir);
                std::filesystem::create_directories(dir);
            }
        }

        monitor.recordSuccess("DirectoryCheck", "必要目录检查和创建完成");
        LOG_INFO("=== 启动前置检查完成 ===");
        return true;
    } catch (const std::exception& e) {
        LOG_ERROR("启动前置检查失败: " + std::string(e.what()));
        core_services::auth_service::getStartupMonitor().recordError("PreStartupCheck",
            "启动前置检查异常: " + std::string(e.what()));
        return false;
    }
}

/**
 * @brief 创建和初始化认证服务
 * @return 服务实例指针，失败返回nullptr
 */
std::unique_ptr<AuthService> createAuthService() {
    try {
        LOG_INFO("=== 开始创建认证服务 ===");

        // 执行启动前置检查
        if (!performPreStartupChecks()) {
            LOG_ERROR("启动前置检查失败");
            return nullptr;
        }

        // 从配置管理器加载服务配置
        LOG_INFO("加载服务配置...");
        auto config = AuthService::Config::fromConfigManager();

        // 验证配置
        LOG_INFO("验证服务配置...");
        std::string validation_error = config.validate();
        if (!validation_error.empty()) {
            LOG_ERROR("服务配置验证失败: " + validation_error);
            return nullptr;
        }
        LOG_INFO("服务配置验证通过");

        // 创建服务实例
        LOG_INFO("创建认证服务实例...");
        auto service = std::make_unique<AuthService>(config);

        // 初始化服务
        LOG_INFO("初始化认证服务组件...");
        if (!service->initialize()) {
            LOG_ERROR("认证服务初始化失败");
            return nullptr;
        }

        LOG_INFO("=== 认证服务创建和初始化成功 ===");
        return service;
    } catch (const std::exception& e) {
        LOG_ERROR("创建认证服务时发生异常: " + std::string(e.what()));
        return nullptr;
    }
}

/**
 * @brief 执行健康检查
 * @param service 服务实例
 * @return 健康检查通过返回true
 */
bool performHealthCheck(AuthService* service) {
    try {
        if (!service) {
            return false;
        }

        // 检查服务运行状态
        if (!service->isRunning()) {
            LOG_WARNING("服务未运行");
            return false;
        }

        // 这里可以添加更多健康检查逻辑
        // 例如：数据库连接检查、Redis连接检查等

        return true;
    } catch (const std::exception& e) {
        LOG_ERROR("健康检查异常: " + std::string(e.what()));
        return false;
    }
}

/**
 * @brief 等待服务运行
 * @param service 服务实例
 */
void waitForService(AuthService* service) {
    LOG_INFO("=== 认证服务已启动，等待请求处理 ===");
    LOG_INFO("服务状态监控已启动");
    LOG_INFO("按 Ctrl+C 优雅关闭服务");

    auto last_health_check = std::chrono::steady_clock::now();
    const auto health_check_interval = std::chrono::seconds(30);

    // 定期检查服务状态
    while (service && service->isRunning()) {
        std::this_thread::sleep_for(std::chrono::seconds(1));

        // 定期健康检查
        auto now = std::chrono::steady_clock::now();
        if (now - last_health_check >= health_check_interval) {
            if (!performHealthCheck(service)) {
                LOG_WARNING("健康检查失败，但服务继续运行");
            } else {
                LOG_DEBUG("健康检查通过");
            }
            last_health_check = now;
        }
    }

    LOG_INFO("服务监控循环结束");
}

/**
 * @brief 主函数
 * @param argc 参数数量
 * @param argv 参数数组
 * @return 程序退出代码
 */
int main(int argc, char* argv[]) {
    // 打印启动横幅
    printBanner();
    
    try {
        std::cout << "=== 游戏微服务认证服务启动程序 ===" << std::endl;

        // 解析命令行参数
        std::string config_file = "../../../../config/auth_service_config.yml";
        if (argc > 1) {
            config_file = argv[1];
        }

        std::cout << "使用配置文件: " << config_file << std::endl;

        // 移除进程锁机制，改为依赖端口独占性（与API Gateway一致）
        std::cout << "\n认证服务将依赖端口独占性防止多实例运行" << std::endl;

        // 第一阶段：加载配置文件
        std::cout << "\n[阶段 1/5] 加载配置文件" << std::endl;
        if (!loadConfiguration(config_file)) {
            std::cerr << "配置文件加载失败，程序退出" << std::endl;
            return EXIT_FAILURE;
        }

        // 第二阶段：初始化日志系统
        std::cout << "\n[阶段 2/5] 初始化日志系统" << std::endl;
        if (!initializeLogging()) {
            std::cerr << "日志系统初始化失败，程序退出" << std::endl;
            return EXIT_FAILURE;
        }

        // 第三阶段：注册信号处理器
        std::cout << "\n[阶段 3/5] 注册信号处理器" << std::endl;
        registerSignalHandlers();
        LOG_INFO("信号处理器注册完成");

        LOG_INFO("=== 认证服务启动开始 ===");

        // 第四阶段：创建和初始化认证服务
        std::cout << "\n[阶段 4/5] 创建和初始化认证服务" << std::endl;
        g_auth_service = createAuthService();
        if (!g_auth_service) {
            LOG_ERROR("认证服务创建失败");
            std::cerr << "认证服务创建失败，程序退出" << std::endl;
            return EXIT_FAILURE;
        }

        // 第五阶段：启动服务
        std::cout << "\n[阶段 5/6] 启动认证服务" << std::endl;
        LOG_INFO("正在启动认证服务...");
        if (!g_auth_service->start()) {
            LOG_ERROR("认证服务启动失败");
            std::cerr << "认证服务启动失败，程序退出" << std::endl;
            return EXIT_FAILURE;
        }

        // 第五阶段：启动HTTP服务器（主线程阻塞）
        std::cout << "\n[阶段 5/5] 启动HTTP服务器" << std::endl;

        auto& monitor = core_services::auth_service::getStartupMonitor();
        monitor.setStage(core_services::auth_service::StartupStage::COMPLETED);

        LOG_INFO("=== 认证服务启动完成 ===");
        std::cout << "认证服务启动成功！" << std::endl;

        // 打印启动摘要
        monitor.printSummary();

        // 启动服务（这会阻塞主线程直到服务停止）
        std::cout << "启动HTTP服务器，主线程将阻塞在此..." << std::endl;
        if (!g_auth_service->start()) {
            LOG_ERROR("认证服务启动失败");
            std::cerr << "认证服务启动失败，程序退出" << std::endl;
            return EXIT_FAILURE;
        }

        // 注意：这里的代码只有在HTTP服务器停止后才会执行
        std::cout << "HTTP服务器已停止，程序即将退出" << std::endl;

        std::cout << "\n=== 开始优雅关闭认证服务 ===" << std::endl;
        LOG_INFO("=== 认证服务关闭开始 ===");

        // 先停止服务，再清理资源
        if (g_auth_service) {
            try {
                std::cout << "正在停止认证服务..." << std::endl;
                LOG_INFO("正在停止认证服务...");

                auto stop_start = std::chrono::steady_clock::now();
                bool stop_success = g_auth_service->stop();
                auto stop_duration = std::chrono::steady_clock::now() - stop_start;
                auto stop_ms = std::chrono::duration_cast<std::chrono::milliseconds>(stop_duration).count();

                if (stop_success) {
                    LOG_INFO("认证服务已停止 (耗时: " + std::to_string(stop_ms) + "ms)");
                    std::cout << "认证服务已停止" << std::endl;
                } else {
                    LOG_WARNING("认证服务停止时返回失败状态，但继续清理资源");
                    std::cout << "认证服务停止时返回失败状态，但继续清理资源" << std::endl;
                }

                std::cout << "正在清理认证服务资源..." << std::endl;
                LOG_INFO("正在清理认证服务资源...");

                auto cleanup_start = std::chrono::steady_clock::now();
                g_auth_service.reset();
                auto cleanup_duration = std::chrono::steady_clock::now() - cleanup_start;
                auto cleanup_ms = std::chrono::duration_cast<std::chrono::milliseconds>(cleanup_duration).count();

                LOG_INFO("认证服务资源已清理 (耗时: " + std::to_string(cleanup_ms) + "ms)");
                std::cout << "认证服务资源已清理" << std::endl;

            } catch (const std::exception& e) {
                LOG_ERROR("停止认证服务时发生异常: " + std::string(e.what()));
                std::cerr << "停止认证服务时发生异常: " << e.what() << std::endl;
                // 不要返回错误，继续清理
            } catch (...) {
                LOG_ERROR("停止认证服务时发生未知异常");
                std::cerr << "停止认证服务时发生未知异常" << std::endl;
                // 不要返回错误，继续清理
            }
        }

        LOG_INFO("=== 认证服务关闭完成 ===");
        std::cout << "=== 认证服务关闭完成 ===" << std::endl;

        // 强制刷新日志
        try {
            common::logger::Logger::getInstance().flushAll();
        } catch (...) {
            // 忽略日志刷新异常
        }

        // 清理启动监控器
        core_services::auth_service::resetStartupMonitor();

        return EXIT_SUCCESS;
        
    } catch (const std::exception& e) {
        std::cerr << "程序运行时发生异常: " << e.what() << std::endl;
        LOG_ERROR("程序运行时发生异常: " + std::string(e.what()));
        
        // 清理资源
        if (g_auth_service) {
            g_auth_service->stop();
            g_auth_service.reset();
        }
        
        return EXIT_FAILURE;
    } catch (...) {
        std::cerr << "程序运行时发生未知异常" << std::endl;
        LOG_ERROR("程序运行时发生未知异常");
        
        // 清理资源
        if (g_auth_service) {
            g_auth_service->stop();
            g_auth_service.reset();
        }
        
        return EXIT_FAILURE;
    }
}
